package org.example.ai04.controller;

import org.example.ai04.dto.ResumeData;
import org.example.ai04.dto.ChatResponse;
import org.example.ai04.service.ChatService;
import org.example.ai04.service.ResumeParserService;
import org.example.ai04.service.ResumeProcessingService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 简历控制器
 * 负责处理简历上传解析和聊天相关功能
 * 结合MVC和RESTful风格的控制器实现
 * - 通过Thymeleaf模板渲染页面(MVC)：处理解析简历等需要页面展示的请求
 * - 通过@ResponseBody返回JSON数据(RESTful)：处理聊天等只需要数据交换的请求
 * 作为前后端交互的桥梁，协调各个服务组件完成简历相关的业务流程
 */
@Controller
public class ResumeController {

    // 日志记录器，用于记录控制器操作和错误信息
    private static final Logger logger = LoggerFactory.getLogger(ResumeController.class);
    
    // 注入简历解析服务，负责调用AI模型解析上传的简历文件，提取结构化数据
    @Autowired
    private ResumeParserService resumeParserService;

    // 注入简历处理服务，负责数据格式转换、简历分析和JSON序列化/反序列化
    @Autowired
    private ResumeProcessingService resumeProcessingService;

    // 注入聊天服务，负责处理用户与简历相关的问答交互
    @Autowired
    private ChatService chatService;

    /**
     * 处理简历上传和解析的POST请求
     * 接收上传的简历文件，调用AI模型解析，并将解析结果展示在resume视图中
     * 
     * @param file 上传的简历文件(MultipartFile格式)
     * @param aiModel 选择的AI模型，支持多个AI模型，默认为"deepseek"
     * @param model Spring MVC模型，用于传递数据到Thymeleaf视图
     * @return 返回"resume"视图名称，由Thymeleaf引擎渲染为HTML页面
     */
    @PostMapping("/parse-resume")
    public String parseResume(@RequestParam("file") MultipartFile file, 
                             @RequestParam(value = "aiModel", required = false, defaultValue = "deepseek") String aiModel, 
                             Model model) {
        logger.info("开始处理简历文件: {}", file.getOriginalFilename());
        logger.info("文件大小: {} bytes", file.getSize());
        logger.info("选择的AI模型: {}", aiModel);

        try {
            // 第一步：调用简历解析服务，使用指定的AI模型解析上传的简历文件
            Map<String, Object> resumeDataMap = resumeParserService.parseResume(file, aiModel);
            logger.info("LLM解析完成，姓名: {}", resumeDataMap.get("name"));

            // 第二步：使用简历处理服务将Map格式数据转换为结构化的ResumeData对象
            ResumeData resumeData = resumeProcessingService.convertMapToResumeData(resumeDataMap);
            
            // 第三步：对简历进行分析，生成评分和改进建议
            ResumeData.ResumeAnalysis analysis = resumeProcessingService.analyzeResume(resumeData, aiModel);
            
            logger.info("简历分析完成，评分: {}", analysis.getOverallScore());

            // 第四步：创建欢迎消息，用于初始化聊天界面
            List<ResumeData.ChatMessage> chatMessages = resumeProcessingService.createWelcomeChat();
            
            // 第五步：将ResumeData对象转换为JSON字符串，便于前端JavaScript使用
            String resumeDataJson = resumeProcessingService.convertToJson(resumeData);

            // 第六步：将所有处理好的数据添加到模型中，传递给Thymeleaf视图
            model.addAttribute("success", true);             // 标记操作成功
            model.addAttribute("resumeData", resumeData);    // 结构化的简历数据对象
            model.addAttribute("resumeDataJson", resumeDataJson); // 简历数据的JSON字符串格式
            model.addAttribute("fileName", file.getOriginalFilename()); // 上传的文件名
            model.addAttribute("analysis", analysis);         // 简历分析结果
            model.addAttribute("chatMessages", chatMessages); // 聊天消息列表
            model.addAttribute("aiModel", aiModel);           // 使用的AI模型

        } catch (Exception e) {
            // 处理简历解析过程中可能出现的所有异常
            logger.error("简历解析失败", e);
            model.addAttribute("success", false);             // 标记操作失败
            model.addAttribute("errorMessage", "简历解析失败: " + e.getMessage()); // 错误信息
        }

        // 返回resume视图页面，无论成功还是失败都会渲染此页面
        return "resume";
    }

    /**
     * 处理与简历相关的聊天请求
     * 提供基于RESTful风格的API接口，接收用户问题并返回AI生成的回答
     * 通过@ResponseBody注解直接返回JSON格式的ChatResponse对象
     * 
     * @param question 用户的问题文本
     * @param resumeDataJson 简历数据的JSON字符串
     * @param chatHistory 聊天历史记录的JSON字符串(可选)
     * @param aiModel 选择的AI模型(可选)
     * @return ChatResponse对象，包含AI生成的回答和更新后的聊天历史记录
     */
    @PostMapping("/chat")
    @ResponseBody
    public ChatResponse chat(@RequestParam String question,
                           @RequestParam String resumeDataJson,
                           @RequestParam(required = false) String chatHistory,
                           @RequestParam(required = false) String aiModel) {
        try {
            // 第一步：从JSON字符串解析简历数据，转换为ResumeData对象
            ResumeData resumeData = resumeProcessingService.parseResumeDataFromJson(resumeDataJson);
            
            // 第二步：解析聊天历史记录，转换为ChatMessage对象列表
            List<ResumeData.ChatMessage> messages = resumeProcessingService.parseChatHistory(chatHistory);
            
            logger.info("收到聊天请求，姓名: {}, 邮箱: {}", resumeData.getName(), resumeData.getEmail());
            logger.info("使用AI模型: {}", aiModel);
            
            // 第三步：确定要使用的AI模型，如果未提供则使用默认的"deepseek"
            String selectedModel = aiModel != null && !aiModel.trim().isEmpty() ? aiModel : "deepseek";
            // 第四步：调用聊天服务，根据简历内容和问题生成回答
            String answer = chatService.chatWithResume(resumeData, question, messages, resumeDataJson, selectedModel);
            
            // 第五步：创建用户消息对象，标记角色为"user"
            ResumeData.ChatMessage userMessage = chatService.createChatMessage("user", question);
            
            // 第六步：创建AI回复消息对象，标记角色为"assistant"
            ResumeData.ChatMessage aiMessage = chatService.createChatMessage("assistant", answer);
            
            // 第七步：将用户消息和AI回复添加到聊天历史中
            messages.add(userMessage);
            messages.add(aiMessage);
            
            // 第八步：返回包含回答和更新后聊天历史的响应对象
            return new ChatResponse(answer, messages);
            
        } catch (Exception e) {
            // 捕获并记录聊天过程中可能发生的所有异常
            logger.error("Chat处理失败", e);
            // 返回包含错误信息的响应，聊天历史为空列表
            return new ChatResponse("抱歉，处理您的消息时出现问题。", new ArrayList<>());
        }
    }


}